import time
import urllib.request
import json
import yaml
import pymongo
from bson import ObjectId
from datetime import datetime
import dateutil.parser

# pip3 install python-dateutil pymongo pyyaml

url = "https://api.weixin.qq.com/cgi-bin/material/batchget_material?access_token={}"

auth_token = ''
cms_mongo = None
wx_article_category = ''
cms_admin_user_id = ''
wx_access_token_request_url = ''


def main():
    time.sleep(60)
    response_token = ''
    while(True):
        print(datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
        try:
            response_token = urllib.request.urlopen(wx_access_token_request_url.format(auth_token))
            access_token = response_token.read().decode('utf-8')
            if len(access_token) < 150:
                print("Error, request access_token failed: {}".format(access_token))
            else:
                print(access_token)
                wx_article_url = url.format(access_token)
                articles_json = get_articles(wx_article_url)
                print("wx articles size: {}".format(len(articles_json['item'])))
                sync_to_mongo(articles_json)
        except Exception as e:
            print(response_token)
            print(e)

            time.sleep(3600)
            continue

        time.sleep(3600)


def convert_to_cms_article(wx_article):
    article_obj = wx_article['content']['news_item'][0]
    update_time = wx_article['update_time']
    iso_date = convert_timestamp_to_iso_date(update_time)
    timestamp_str = datetime.now().strftime("%s")
    cms_article = {
        "category": ObjectId(wx_article_category),
        "title": article_obj['title'],
        "alias": wx_article['media_id'].lower() + timestamp_str,
        "user": ObjectId(cms_admin_user_id),
        "abstract": "",
        "content": "",
        "extensions": {
            "img": article_obj['thumb_url'],
            "url": article_obj['url']
        },
        "tags": [],
        "media": [],
        "reading": {
            "createAt": {"month": iso_date, "week": iso_date, "day": iso_date},
            "month": 0, "week": 0, "day": 0, "total": 0
        },
        "date": iso_date,
        "deleted": False,
        "status": "pushed",
        "__v": 0
    }
    return cms_article


def save_to_mongo(cms_article):
    print("save article: ", cms_article)
    cms_collection = cms_mongo["contents"]
    cms_collection.insert_one(cms_article)


def sync_to_mongo(articles_json):
    wx_articles = articles_json['item']

    oldest_article = wx_articles[-1]
    oldest_article_time = oldest_article['update_time']
    cms_collection = cms_mongo["contents"]
    current_articles = cms_collection.find({'category': ObjectId(wx_article_category), 'deleted': False,
                                            "date": {"$gte": convert_timestamp_to_iso_date(oldest_article_time)}})

    current_articles_name_list = []
    for article in current_articles:
        current_articles_name_list.append(article['title'])

    print("current cms articles size: {}".format(len(current_articles_name_list)))
    for article in wx_articles:
        article_obj = article['content']['news_item'][0]
        if article_obj['title'] is None or article_obj['title'] == '':
            continue
        if article_obj['title'] not in current_articles_name_list:
            cms_article_obj = convert_to_cms_article(article)
            save_to_mongo(cms_article_obj)


def get_articles(request_url):
    request_data = json.dumps({"type": "news", "offset": "0", "count": "30"})
    request_data = str(request_data).encode('utf-8')

    headers = {"Content-Type": "application/json"}
    request_wx = urllib.request.Request(request_url, data=request_data, method='POST', headers=headers)
    response_wx = urllib.request.urlopen(request_wx)
    articles_content = response_wx.read()
    articles_str = articles_content.decode('utf-8')
    return json.loads(articles_str)


def convert_timestamp_to_iso_date(timestamp):
    iso_date = datetime.utcfromtimestamp(timestamp).isoformat()
    return dateutil.parser.parse(iso_date)


if __name__ == '__main__':
    with open("/opt/wx/config.yaml", "r") as file:
        wx_config = file.read()
        wx_config_yaml = yaml.safe_load(wx_config)
        auth_token = wx_config_yaml['auth']['token']
        mongo_host = wx_config_yaml['mongo']['host']
        mongo_port = wx_config_yaml['mongo']['port']
        mongo_user = wx_config_yaml['mongo']['user']
        mongo_pass = wx_config_yaml['mongo']['pass']
        wx_article_category = wx_config_yaml['cms']['category']['wx']
        cms_admin_user_id = wx_config_yaml['cms']['user']['admin_id']
        wx_access_token_request_url = wx_config_yaml['auth']['url']
    mongo_conn = pymongo.MongoClient(mongo_host, mongo_port, username=mongo_user,
                                     password=mongo_pass, authSource="nodercms", authMechanism="SCRAM-SHA-1")
    cms_mongo = mongo_conn["nodercms"]
    print("started wechat_articles.py")
    # sync_to_mongo(None)
    main()
